-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local log = require 'mc.logging'
local bs = require 'mc.bitstring'
local definition = require 'canbus.definition'
local canbus_collection = require 'canbus.collection'

local debug_handler = {}

local function check_channel(channel)
    local chan = tonumber(channel)
    if chan == 0 or chan == 1 then
        return true, chan
    end

    log:mdbctl_log('Failed: invalid channel: %s.\n', channel)
    return false
end

function debug_handler.send_boardcast(channel)
    local ok, chan = check_channel(channel)
    if not ok then
        return false
    end

    log:notice('prepare to send test boardcast to channel [%d]', chan)
    log:mdbctl_log('Sending test boardcast ...\n')

    -- generate a test boardcast message [test boardcast identifier is fixed to 0]
    local payload = bs.new([[<<cmd, reserved, identifier, channel>>]]):pack({
        cmd = definition.can_cmds.DEBUG_BOARDCAST_REQ,
        reserved = 0,
        identifier = 0,
        channel = channel
    })
    if not payload then
        log:error('generate test boardcast message payload failed.')
        return false
    end

    -- send via channel with boardcast
    ok = canbus_collection.get_instance():send(payload, channel, definition.dest.BOARDCAST)
    if not ok then
        log:mdbctl_log('Send test boardcast failed.\n')
        return false
    end

    log:mdbctl_log('Send test boardcast success.\n')
    return true
end

function debug_handler.print_metrics(channel)
    local chan = channel
    if not channel then
        chan = 0xFF
    end
    log:notice('prepare to print metrics for channel [%d]', chan)

    local metrics = canbus_collection.get_instance():get_metrics(chan)
    if not (metrics and next(metrics)) then
        log:mdbctl_log('There is no metrics.\n')
        return ''
    end

    -- |------------|----------------|----------------|----------------|
    -- |CAN通道编号  |接收消息数量统计   |发送消息数量统计   |发送失败数量统计  |
    -- |------------|----------------|----------------|----------------|
    local result = {}
    local json = require 'cjson'
    local ok, msg = pcall(function ()
        for _, v in pairs(metrics) do
            table.insert(result, json.encode(v))
        end
    end)
    if not ok then
        log:mdbctl_log('Get metrics failed.')
        log:error('metrics encode failed, error: %s', msg)
        return ''
    end

    return result
end

return debug_handler